#ifndef IFILEBUFFER_H
#define IFILEBUFFER_H

#include <QString>
#include <QObject>

class IFileBuffer : public QObject
{
    Q_OBJECT

public:
    IFileBuffer() : QObject() {}
    virtual ~IFileBuffer(){}

    //! Проверяет наличие доступа к рабочему потоку файлового буффера и резервирует его в случае успеха
    /*!
     * \brief holdLoad
     * \return Описание ошибки, если зарезервировать процесс нельзя. Если инициация прошла успешно,
     * возвращает QString()
     */
    virtual QString holdLoad() = 0;

    //! Загружает в буфер заданный файл
    /*!
     * \brief FileBuffer::loadFile
     * \param fName путь к загружаемому файлу     
     */
    virtual void loadFile(QString fName) = 0;

    virtual QString holdSave() = 0;

    //! Сохраняет ранее загруженный файл под заданным именем
    /*!
     * \brief saveFile
     * \param fName путь, по которому должны быть сохранены данные из буфера    
     */
    virtual void saveFile(QString fName) = 0;

    //! Отказ резервирования потока
    /*!
     * \brief releaseOp
     */
    virtual void release() = 0;

    virtual QString holdClear() = 0;

    //! Удаляет из буфера содержимое загруженного ранее файла
    virtual void clearData() = 0;

    //! Возвращает описание ошибки последней операции, если была ошибка, иначе QString()
    virtual QString getLastError() = 0;

    enum State {FREE, LOADING, LOADED, SAVING};

    //! Возвращает состояние буффера файлов
    virtual IFileBuffer::State getState() = 0;

    //! Возвращает название загруженного файла
    /*!
     * \brief getFileName
     * \return Название загруженного файла. Если файл не загружен, то возвращает QString()
     */
    virtual QString getFileName() = 0;

    //! Возвращает размер загруженного файла в байтах
    /*!
     * \brief getFileSize
     * \return размер загруженного файла в байтах. Если файл не загружен, то -1.
     */
    virtual qint64 getFileSize() = 0;

    //! Возвращает количество обработанных байт, если буффер находится в переходном состоянии
    virtual qint64 getBytesProcessed() = 0;

public slots:

    //! Устанваливает текущую операцию на паузу или выводит её из состояния паузы, если на момент вызова она на паузе
    virtual void trigger() = 0;

    //! Отмена текущей операции
    virtual void stop() = 0;

signals:    

    //! сигнал о начале загрузки файла
    void beginFileLoading(qint64 fileSize);

    //! сигнал об успешной загрузке файла
    /*!
     * \brief fileLoaded
     * \param fileName имя загруженного файла
     * \param fileSize размер загруженного файла в байтах
     */
    void fileLoaded(QString fileName, qint64 fileSize);

    //todo добавить информацию, характеризующую состояние буфера после ошибки, чтобы не опрашивать
    //! сигнал об ошибке в процессе загрузки файла
    /*!
     * \brief fileLoadingError
     * \param fileName имя файла, при попытке загрузке которого произошла ошибка
     * \param error описание произошедшей ошибки
     * \param newState тип состояния, в которое перешел буфер после неудачной попытки загрузки файла
     */
    void fileLoadingError(QString fileName, QString error, IFileBuffer::State newState);

    //! сигнал о начале сохранения файла
    void beginFileSaving(qint64 fileSize);

    //! сигнал об успешном созранении файла
    /*!
     * \brief fileSaved
     * \param fileName имя файла, который был сохранен
     */
    void fileSaved(QString fileName);

    //! сигнал об ошибке в процессе сохранения файла
    /*!
     * \brief fileSavingError
     * \param fileName имя файла, при сохранении которого произошла ошибка
     * \param error описание произошедшей ошибки
     */
    void fileSavingError(QString fileName, QString error);

    //! сигнал об окончании процесса очистки памяти
    void dataCleared();

    //! Сигнал о приостановке текущей операции
    void opPaused();

    //! Сигнал о возобновлении текущей операции
    void opResumed();
};

#endif // IFILEBUFFER_H
